EventDispatcher = EventDispatcher or Class("EventDispatcher")

---@diagnostic disable-next-line: duplicate-set-field
function EventDispatcher:ctor()
    self._events = {}
    self.emitted = {}
end

function EventDispatcher:on(eventID, callback, caller, ...)
    if not eventID then
        Console.error("eventID can't be nil!")
        return
    end
    if not callback then
        Console.error("eventID:"..eventID .. " callback is nil")
    end
    local event = {eventID = eventID, callback = callback, caller = caller}
    if not self._events[eventID] then
        self._events[eventID] = {}
    end
    local tbl = self._events[eventID]
    table.insert(tbl, event)
    return event
end

function EventDispatcher:once(eventID, callback, caller)
    local event = self:on(eventID, callback, caller)
    event.once = true
end

function EventDispatcher:emit(eventID, ...)

    local tbl = self._events[eventID]
    if not tbl then
        return
    end
    for _, v in ipairs(tbl) do
        if v.caller then
            v.callback(v.caller, ...)
        else
            v.callback(...)
        end
        if v.once then
            v.dirty = true
        end
    end

    -- 移除一次性事件
    for i = #tbl, 1, -1 do
        local event = tbl[i]
        if event.dirty then
            table.remove(tbl, i)
        end
    end
end

function EventDispatcher:offAll()
    self._events = {}
end

function EventDispatcher:off(eventID, callback, caller)
    if not eventID then
        error("eventID can't be nil!")
    end
    if not callback and not caller then
        self._events[eventID] = nil
        return
    end
    local tbl = self._events[eventID]
    if not tbl then
        return
    end
    if callback and not caller then
        for i = #tbl, 1, -1 do
            local event = tbl[i]
            if event.callback == callback then
                table.remove(tbl, i)
            end
        end
        return
    end
    for i = #tbl, 1, -1 do
        local event = tbl[i]
        if event.callback == callback and event.caller == caller then
            table.remove(tbl, i)
        end
    end
end

local eventCount = 1
function RegisterEvents(list)
    local tbl = {}
    for _, k in ipairs(list) do
        tbl[k] = eventCount
        eventCount = eventCount + 1
    end
    return tbl
end

EventDispatcher.global = EventDispatcher.new()
GlobalEvent = Enum{
    "WindowResized",
    "OnSelectDataNode"
}